home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / earcd / mus / play / mikmod.lzh / mikmod / drv_pau.c < prev    next >
C/C++ Source or Header  |  1997-01-28  |  8KB  |  325 lines

  1. /*
  2.  
  3. Name:
  4. DRV_PAU.C
  5.  
  6. Description:
  7. Mikmod driver for output to 8-bit Paula channels.
  8.  
  9. Portability:
  10.  
  11. This code is Amiga chipset specific.
  12.  
  13. This port was done on 28/01/97 by Tony Bybell.
  14. bybell@cse.psu.edu
  15.  
  16. */
  17.  
  18. #include <exec/types.h>
  19. #include <exec/memory.h>
  20. #include <devices/audio.h>
  21. #include <graphics/gfxbase.h>
  22. #include <proto/all.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #define  AMIGA_PAULADRV
  26. #include "mikmod.h"
  27.  
  28. #define PAULABUFFERSIZE 8192
  29.  
  30. struct  GfxBase *LocalGfxBase;
  31. UBYTE   whichchannell[]={1,8};
  32.  
  33. UBYTE   whichchannelr[]={2,4};
  34.  
  35. int     DBFlag=0;
  36. short   IsSixteenBit=0;
  37. short   IsStereo=0;
  38.  
  39. struct  IOAudio *AIOptrl=NULL;
  40. struct  MsgPort *portl=NULL;
  41. struct  Message *msgl=NULL;
  42. ULONG   devicel;
  43.  
  44. struct  IOAudio *AIOptrr=NULL;
  45. struct  MsgPort *portr=NULL;
  46. struct  Message *msgr=NULL;
  47. ULONG   devicer;
  48.  
  49.  
  50. LONG    clock=3579545;
  51. LONG    slen=0;
  52.  
  53. char *PAULA_DMABUF=NULL;
  54. char *PAULA_LEFT[2], *PAULA_RIGHT[2];
  55.  
  56.  
  57. static void Paula_Exit(void)
  58. {
  59. int i;
  60.  
  61. VC_Exit();
  62.  
  63.         if(portr)
  64.                 {
  65.                 DeletePort(portr);
  66.                 portr=NULL;
  67.                 }
  68.  
  69.         if(AIOptrr)
  70.                 {
  71.                 CloseDevice((struct IORequest *)AIOptrr);
  72.                 FreeMem(AIOptrr,sizeof(struct IOAudio));
  73.                 AIOptrr=NULL;
  74.                 }
  75.                 
  76.         if(portl)
  77.                 {
  78.                 DeletePort(portl);
  79.                 portl=NULL;
  80.                 }
  81.  
  82.         if(AIOptrl)
  83.                 {
  84.                 CloseDevice((struct IORequest *)AIOptrl);
  85.                 FreeMem(AIOptrl,sizeof(struct IOAudio));
  86.                 AIOptrl=NULL;
  87.                 }
  88.  
  89.         for(i=0;i<2;i++)
  90.                 {
  91.                 if(PAULA_LEFT[i])FreeMem(PAULA_LEFT[i], slen);
  92.                 if(PAULA_RIGHT[i])FreeMem(PAULA_RIGHT[i],slen);
  93.                 PAULA_LEFT[i]=PAULA_RIGHT[i]=NULL;
  94.                 }
  95.  
  96.         if(PAULA_DMABUF)
  97.                 {
  98.                 FreeMem(PAULA_DMABUF,  PAULABUFFERSIZE);
  99.                 PAULA_DMABUF=NULL;
  100.                 }
  101. }
  102.  
  103.  
  104. static int Paula_IsThere(void)
  105. {
  106. return 1;       /* Paula is always there */
  107. }
  108.  
  109.  
  110. static int Paula_Init(void)
  111. {
  112. char *filter=(char *)0xbfe001;
  113.  
  114. *filter|=0x02;  /* Turn off the low pass filter */
  115.  
  116. if(IsSixteenBit=(md_mode&DMODE_16BITS)) 
  117.         slen=PAULABUFFERSIZE/4; else
  118.         slen=PAULABUFFERSIZE/2;
  119.  
  120. if(!(IsStereo=(md_mode&DMODE_STEREO))) slen<<=1;
  121.  
  122.  
  123. PAULA_DMABUF=(char *)AllocMem(PAULABUFFERSIZE,MEMF_PUBLIC);
  124. PAULA_LEFT[0]=(char *)AllocMem(slen,MEMF_CHIP|MEMF_CLEAR);
  125. PAULA_LEFT[1]=(char *)AllocMem(slen,MEMF_CHIP|MEMF_CLEAR);
  126. PAULA_RIGHT[0]=(char *)AllocMem(slen,MEMF_CHIP|MEMF_CLEAR);
  127. PAULA_RIGHT[1]=(char *)AllocMem(slen,MEMF_CHIP|MEMF_CLEAR);
  128. if((!PAULA_DMABUF)||(!PAULA_LEFT[0])||(!PAULA_LEFT[1])
  129.         ||(!PAULA_RIGHT[0])||(!PAULA_RIGHT[1]))
  130.         {
  131.         printf("Could not malloc buffer memory!\n");
  132.         Paula_Exit();
  133.         return(0);
  134.         }
  135.  
  136.  
  137. if(!(LocalGfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0L)))
  138.         {
  139.         printf("Could not open graphics.library!\n");
  140.         Paula_Exit();
  141.         return(0);
  142.         }
  143.  
  144. if(LocalGfxBase->DisplayFlags & PAL) clock=3546895; else clock=3579545;
  145. CloseLibrary((struct Library *)LocalGfxBase);
  146.  
  147. if(!(AIOptrl=(struct IOAudio *)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR)))
  148.         {
  149.         printf("Could not alloc IOAudio structure mem!\n");
  150.         Paula_Exit();
  151.         return(0);
  152.         }
  153.  
  154. if(!(portl=CreatePort(0,0)))
  155.         {
  156.         printf("Could not create reply port!\n");
  157.         Paula_Exit();
  158.         return(0);
  159.         }
  160.  
  161. AIOptrl->ioa_Request.io_Message.mn_ReplyPort     =       portl;
  162. AIOptrl->ioa_Request.io_Message.mn_Node.ln_Pri   =       0;
  163. AIOptrl->ioa_Request.io_Command                  =       ADCMD_ALLOCATE;
  164. AIOptrl->ioa_Request.io_Flags                    =       ADIOF_NOWAIT;
  165. AIOptrl->ioa_AllocKey                            =       0;
  166. AIOptrl->ioa_Data                                =       whichchannell;
  167. AIOptrl->ioa_Length                              =       sizeof(whichchannell);
  168.  
  169. if(devicel=OpenDevice("audio.device",0L,(struct IORequest *)AIOptrl,0L))
  170.         {
  171.         printf("Could not grab audio.device!\n");
  172.         Paula_Exit();
  173.         return(0);
  174.         }
  175.  
  176.  
  177. if(!(AIOptrr=(struct IOAudio *)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR)))
  178.         {
  179.         printf("Could not alloc IOAudio structure mem!\n");
  180.         Paula_Exit();
  181.         return(0);
  182.         }
  183.  
  184. if(!(portr=CreatePort(0,0)))
  185.         {
  186.         printf("Could not create reply port!\n");
  187.         Paula_Exit();
  188.         return(0);
  189.         }
  190.  
  191. AIOptrr->ioa_Request.io_Message.mn_ReplyPort     =       portr;
  192. AIOptrr->ioa_Request.io_Message.mn_Node.ln_Pri   =       0;
  193. AIOptrr->ioa_Request.io_Command                  =       ADCMD_ALLOCATE;
  194. AIOptrr->ioa_Request.io_Flags                    =       ADIOF_NOWAIT;
  195. AIOptrr->ioa_AllocKey                            =       0;
  196. AIOptrr->ioa_Data                                =       whichchannelr;
  197. AIOptrr->ioa_Length                              =       sizeof(whichchannelr);
  198.  
  199. if(devicer=OpenDevice("audio.device",0L,(struct IORequest *)AIOptrr,0L))
  200.         {
  201.         printf("Could not grab audio.device!\n");
  202.         Paula_Exit();
  203.         return(0);
  204.         }
  205.  
  206. AIOptrl->ioa_Request.io_Message.mn_ReplyPort     =       portl;
  207. AIOptrl->ioa_Request.io_Command                  =       CMD_WRITE;
  208. AIOptrl->ioa_Request.io_Flags                    =       ADIOF_PERVOL;
  209. AIOptrl->ioa_Data                                =       (BYTE *)PAULA_LEFT[0];
  210. AIOptrl->ioa_Length                              =       slen;
  211. AIOptrl->ioa_Period                              =       clock/md_mixfreq;
  212. AIOptrl->ioa_Volume                              =       64;
  213. AIOptrl->ioa_Cycles                              =       1;
  214.  
  215. AIOptrr->ioa_Request.io_Message.mn_ReplyPort     =       portr;
  216. AIOptrr->ioa_Request.io_Command                  =       CMD_WRITE;
  217. AIOptrr->ioa_Request.io_Flags                    =       ADIOF_PERVOL;
  218. AIOptrr->ioa_Data                                =       (BYTE *)PAULA_RIGHT[0];
  219. AIOptrr->ioa_Length                              =       slen;
  220. AIOptrr->ioa_Period                              =       clock/md_mixfreq;
  221. AIOptrr->ioa_Volume                              =       64;
  222. AIOptrr->ioa_Cycles                              =       1;
  223.  
  224. BeginIO((struct IORequest *)AIOptrl);
  225. BeginIO((struct IORequest *)AIOptrr);
  226.  
  227.  
  228. if(!VC_Init()){ return 0; }
  229. return 1;
  230. }
  231.  
  232.  
  233. static void Paula_Update(void)
  234. {
  235. short i;
  236. int db;
  237. char *buf, *left, *right;
  238. ULONG signals;
  239.  
  240.  
  241. Wait(1L<<portl->mp_SigBit);      
  242. msgl=GetMsg(portl);      
  243. signals=Wait((1L<<portr->mp_SigBit)|SIGBREAKF_CTRL_C);      
  244. msgr=GetMsg(portr);
  245.  
  246.  
  247. AIOptrl->ioa_Data=(BYTE *)PAULA_LEFT[DBFlag];
  248. if(IsStereo)
  249.         AIOptrr->ioa_Data=(BYTE *)PAULA_RIGHT[DBFlag]; else
  250.         AIOptrr->ioa_Data=(BYTE *)PAULA_LEFT[DBFlag];
  251.  
  252.  
  253. BeginIO((struct IORequest *)AIOptrl);
  254. BeginIO((struct IORequest *)AIOptrr);
  255.  
  256.  
  257. db=1-DBFlag;
  258. buf=PAULA_DMABUF;
  259. left=PAULA_LEFT[db];
  260. right=PAULA_RIGHT[db];
  261.  
  262.     VC_WriteBytes(PAULA_DMABUF,PAULABUFFERSIZE);
  263.  
  264. if(IsStereo)
  265. {
  266. if(IsSixteenBit)
  267.         for(i=0;i<slen;i++)
  268.                 {
  269.                 *left++=*buf;   buf+=2;
  270.                 *right++=*buf;  buf+=2;
  271.                 }
  272.         else
  273.         {
  274.         for(i=0;i<slen;i++)
  275.                 {
  276.                 *left++=(*buf++)^0x80;  
  277.                 *right++=(*buf++)^0x80; 
  278.                 }
  279.         }
  280. }
  281. else
  282. {
  283. if(IsSixteenBit)
  284.         for(i=0;i<slen;i++)
  285.                 {
  286.                 *left++=*buf;   buf+=2;
  287.                 }
  288.         else
  289.         {
  290.         for(i=0;i<slen;i++)
  291.                 {
  292.                 *left++=(*buf++)^0x80;  
  293.                 }
  294.         }
  295. }
  296. DBFlag=db;
  297.  
  298. if(signals&SIGBREAKF_CTRL_C)
  299.         {
  300.         printf("** BREAK **\n");
  301.         Paula_Exit();
  302.         exit(0);
  303.         }
  304. }
  305.  
  306.  
  307.  
  308. DRIVER drv_pau={
  309.     NULL,
  310.     "Eight-bit Paula sound output",
  311.     "Paula Eight-bit output driver v1.0",
  312.     Paula_IsThere,
  313.     VC_SampleLoad,
  314.     VC_SampleUnload,
  315.     Paula_Init,
  316.     Paula_Exit,
  317.     VC_PlayStart,
  318.     VC_PlayStop,
  319.     Paula_Update,
  320.     VC_VoiceSetVolume,
  321.     VC_VoiceSetFrequency,
  322.     VC_VoiceSetPanning,
  323.     VC_VoicePlay
  324. };
  325.